package com.taptech.doufu.net.retrofit.api;

import android.content.Context;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.taptech.doufu.app.WeMediaApplication;
import com.taptech.doufu.bean.cartoon.ReadStatus;
import com.taptech.doufu.bean.cartoon.RedaStatusDeserializer;
import com.taptech.doufu.bean.novel.PayInfoBean;
import com.taptech.doufu.bean.novel.PayInfoBeanDeserializer;
import com.taptech.doufu.constant.Constant;
import com.taptech.doufu.util.AppUtil;
import com.taptech.doufu.weex.http.TFCookieUtil;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * api server
 */
public class ApiClient {

    public String BASE_URL = ApiServer.BASE_URL;

    public static final String SEX_TYPE_BL = "1";//彩虹
    public static final String SEX_TYPE_UN_BL = "3";//言情
    public static final String SEX_TYPE_NO = "0";//不做区分

    private Context mContext;
    public ApiServer apiService;
    private Retrofit retrofit = null;
    private OkHttpClient okHttpClient = null;
    private String sexType = SEX_TYPE_NO;


    private boolean isUseCache = true;
    private int DEFAULT_CACHE_TIME = 60;//默认缓存时间
    private static final int TIMEOUT_DISCONNECT = 60 * 60 * 24 * 7; //无网络时最大缓存为 7 day

    private volatile static ApiClient apiClient;


    public ApiClient() {
    }

    public static ApiClient getInstance() {
        if (apiClient == null) {
            synchronized (ApiClient.class) {
                if (apiClient == null) {
                    apiClient = new ApiClient();
                    apiClient.init(WeMediaApplication.getInstance());
                }
            }
        }
        return apiClient;
    }

    public ApiServer getService() {
        if (apiService == null && retrofit != null) {
            apiService = retrofit.create(ApiServer.class);
        }
        return apiService;
    }

    public void init(Context context) {
        this.mContext = context;
        initOkHttp();
        initRetrofit();
        if (apiService == null) {
            apiService = retrofit.create(ApiServer.class);
        }
    }

    /**
     * 设置性向 默认为不做区分
     *
     * @param sexType
     */
    public ApiClient setSexType(String sexType) {
        this.sexType = sexType;
        return apiClient;
    }

    /**
     * 是否使用缓存
     *
     * @param useCache
     */
    public ApiClient setUseCache(boolean useCache) {
        isUseCache = useCache;
        return apiClient;
    }

    private static final String TAG = ApiClient.class.getSimpleName();
    private void initOkHttp() {
        Log.d(TAG, "initOkHttp: ");
        File cacheFile = new File(mContext.getCacheDir(), "httpCache");
        final Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);

        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(logInterceptor);
//        builder.addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR);
        builder.addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE);
        builder.cache(cache);
        builder.addInterceptor(HEADER_INTERCEPTOR);
//        builder.addInterceptor(new SaveCookiesInterceptor(mContext));
//        builder.addInterceptor(new AddCookiesInterceptor(mContext));
        builder.connectTimeout(10, TimeUnit.SECONDS);
        builder.readTimeout(20, TimeUnit.SECONDS);
        builder.writeTimeout(20, TimeUnit.SECONDS);
        builder.retryOnConnectionFailure(true);
        builder.addInterceptor(chain -> {
            Request request = chain.request();
            HttpUrl oldHttpUrl = request.url();
            if (oldHttpUrl.host().contains("doufu.la")) {
                Request.Builder builder1 = request.newBuilder();
                //重建新的HttpUrl，配置成我们需要的
                HttpUrl newFullUrl = oldHttpUrl
                        .newBuilder()
                        .scheme(oldHttpUrl.scheme())
                        .host(oldHttpUrl.host().replace("doufu.la",Constant.HOST_END_PAST))    //新的url的域名
                        .port(oldHttpUrl.port())
                        .build();
                return chain.proceed(builder1.url(newFullUrl).build());
            } else if (oldHttpUrl.host().contains("doufu.douhuayuedu.com")) {
                Request.Builder builder1 = request.newBuilder();
                //重建新的HttpUrl，配置成我们需要的
                HttpUrl newFullUrl = oldHttpUrl
                        .newBuilder()
                        .scheme(oldHttpUrl.scheme())
                        .host(oldHttpUrl.host().replace("doufu.douhuayuedu.com",Constant.HOST_NAME))    //新的url的域名
                        .port(oldHttpUrl.port())
                        .build();
                return chain.proceed(builder1.url(newFullUrl).build());
            } else{
                Request original = chain.request();
                Request.Builder requestBuilder = original.newBuilder();
                Request request1 = requestBuilder.build();
                return chain.proceed(request1);
            }
        });
        okHttpClient = builder.build();
    }

    private void initRetrofit() {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(ReadStatus.class,new RedaStatusDeserializer())
                .registerTypeAdapter(PayInfoBean.class,new PayInfoBeanDeserializer())
                .create();
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }


    /**
     * 有网络拦截器
     */
    Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            okhttp3.Response originalResponse = chain.proceed(chain.request());
            //获取retrofit @headers里面的自定义 cache 参数
            String cache = chain.request().header(ApiServer.CACHE_KEY);
            String cacheControl = originalResponse.header("Cache-Control");
            if (cacheControl == null) {
                //if cache value is null，cache time is MAX CACHE TIME，else is cache value
                if (cache == null || "".equals(cache)) {
                    cache = DEFAULT_CACHE_TIME + "";
                }
                originalResponse = originalResponse.newBuilder()
                        .header("Cache-Control", "public, max-age=" + cache + ", must-revalidate ")
                        .build();
                return originalResponse;
            } else {
                return originalResponse;
            }
        }
    };

    /**
     * 无网络拦截器
     */
    Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!AppUtil.IsNetworkConnected(mContext)) {
                request = request.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=" + TIMEOUT_DISCONNECT)
                        .build();
            }
            return chain.proceed(request);
        }
    };

    /**
     * header 拦截器
     */
    Interceptor HEADER_INTERCEPTOR = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();
            Request.Builder requestBuilder = originalRequest.newBuilder()
                    .header("Cookie", TFCookieUtil.cookieHeader(TFCookieUtil.getCookies()))
                    .header("Content-Type", "application/json")
                    .header("Accept", "application/json")
                    .method(originalRequest.method(), originalRequest.body());
            if (!isUseCache) {
                requestBuilder.cacheControl(CacheControl.FORCE_NETWORK);
            }
            initConfig();
            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    };

    private void initConfig() {
        isUseCache = true;
    }


}
